feat(linear): agent-session types + kind discriminator (chat@4.31/#151 — L1/5)#168
Conversation
…— L1/5) Port the Linear agent-session type surface from upstream packages/adapter-linear/src/types.ts (vercel/chat, adapter-linear 4.27.0 / chat@4.31.0). TYPES + kind-discriminator plumbing only; agent-session webhook routing / emit / fetch logic lands in L3/L4/L5. - LinearThreadId gains optional agent_session_id; add LinearAgentSessionThreadId (required agent_session_id). - LinearAdapterConfig gains mode: Literal["agent-sessions", "comments"], default "comments" (config.mode ?? "comments", index.ts:236); exposed via the LinearAdapter.mode property. - LinearRawMessage becomes a discriminated union on kind: the existing comment variant (LinearCommentRawMessage, kind="comment") plus the new LinearAgentSessionCommentRawMessage (kind="agent_session_comment", agentSessionId, optional agentSessionPromptContext). All four existing comment producers in adapter.py now set kind="comment" (emit/parse symmetry — a raw message without kind would break the union). - Hand-author AgentSessionEventWebhookPayload (+ nested SDK-mirror TypedDicts) to match the @linear/sdk/webhooks shape upstream index.ts consumes; raw Linear camelCase wire keys kept verbatim. Extend the LinearWebhookPayload union to include it. Re-export the new public types from the linear package __init__ for L2–L5. Tests: structural/typing coverage (mode default, thread-id fields, kind discriminator on every existing producer, agent-session variant + webhook payload shape). pyrefly-clean (src 0, test file 0 / 1 justified ignore).
|
Warning Review limit reached
More reviews will be available in 40 minutes and 29 seconds. Learn how PR review limits work. Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file). ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits. 🚦 How do rate limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Code Review
This pull request introduces support for Linear agent-session types and configuration modes ('comments' or 'agent-sessions') in the Linear adapter. It adds new type definitions, updates the adapter configuration to support the mode parameter, refactors the raw message types into a discriminated union, and includes comprehensive unit tests to verify the structural correctness of these new types. I have no feedback to provide as there are no review comments.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c0b7cf1bcb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| # handling. Defaults to "comments". Use "agent-sessions" for app-actor | ||
| # installs. Faithful port of upstream ``config.mode ?? "comments"`` | ||
| # (types.ts:67, index.ts:236). | ||
| mode: LinearAdapterMode | None = None |
There was a problem hiding this comment.
Preserve existing config positional arguments
Adding mode here changes the generated positional __init__ for all LinearAdapter*Config dataclasses. Existing callers that pass positional args after logger now have their user_name bound to mode, their webhook_secret bound to user_name, and so on, which can make LinearAdapter fail authentication/webhook-secret setup or silently use the wrong bot name. Make this new option keyword-only (or otherwise avoid shifting the public positional signature).
Useful? React with 👍 / 👎.
| """ | ||
|
|
||
| # Required for agent-session threads (narrows the optional base field). | ||
| agent_session_id: str = "" |
There was a problem hiding this comment.
This subclass is documented and exported as the required-session form, but the default allows LinearAgentSessionThreadId(issue_id="...") to construct a value with agent_session_id == "". Code that accepts this type can therefore proceed with an empty Linear agent-session id instead of failing at the call site, so please validate it (or make the field truly required/keyword-only required).
Useful? React with 👍 / 👎.
First of the 5-PR Wave D (issue #151): the foundational TYPES layer for Linear agent sessions. Faithful port of the agent-session type surface from upstream
packages/adapter-linear/src/types.ts(vercel/chat, adapter-linear 4.27.0 / chat@4.31.0).Scope (STRICT): TYPES + the
kinddiscriminator plumbing only. No agent-session webhook routing / emit / fetch logic — those land in L3/L4/L5. CHANGELOG untouched.Types added (vs upstream
types.ts)LinearAdapterMode = Literal["agent-sessions", "comments"](LinearAdapterMode, types.ts:44).LinearAdapterBaseConfig.modefield; default resolved to"comments"inLinearAdapter.__init__(config.mode ?? "comments", index.ts:236), exposed via a newLinearAdapter.modeproperty (mirrorsprotected readonly mode, index.ts:201).LinearThreadId.agent_session_id: str | None = None(optional;LinearThreadId.agentSessionId, types.ts:189).LinearAgentSessionThreadId— subclass narrowingagent_session_idto requiredstr(LinearThreadId & { agentSessionId: string }, types.ts:203).LinearRawMessageis now a discriminated union onkind:LinearCommentRawMessage(kind="comment") +LinearAgentSessionCommentRawMessage(kind="agent_session_comment",agentSessionId, optionalagentSessionPromptContext). Faithful to types.ts:258–281.AgentSessionEventWebhookPayload(+ nested SDK-mirror TypedDicts:AgentSessionWebhookPayload,AgentActivityWebhookPayload, child comment/issue/user payloads, guidance). Hand-authored to match the@linear/sdk/webhooksshape that upstreamindex.tsconsumes; raw Linear camelCase wire keys kept verbatim (external JSON). Added to theLinearWebhookPayloadunion.__init__for L2–L5.kind-discriminator audit (every producer set)
All four
LinearRawMessageconstruction sites inadapter.pyare comment-based and now setkind="comment"viaLinearCommentRawMessage:_webhook_comment_to_message(was line 647)post_message(was 705)edit_message(was 758)_comment_node_to_message(was 965)A test exercises each producer path and asserts
raw["kind"] == "comment", so a future producer that forgets the discriminator regresses.Config mode default
"comments"(faithful to upstream; there is no env var formodeupstream — onlyconfig.mode ?? "comments").Gauntlet
audit_test_quality.py: 0 hard failures (no warnings reference the new file)# type: ignore[misc]on the frozen-mutation test)What L2–L5 consume from these types
AgentSessionEventWebhookPayload, theLinearWebhookPayloadunion, andLinearAdapter.modeto gateAgentSessionEventhandling.LinearAgentSessionCommentRawMessage(kind="agent_session_comment",agentSessionId,agentSessionPromptContext) emitted from the agent-session parse path.LinearAgentSessionThreadId(requiredagent_session_id) andLinearThreadId.agent_session_idfor encode/decode + agent-activity creation.🤖 Generated with Claude Code